/* the following array simplifies scanline origin offset
   lookup in the hires screen area...
   HB stands for High-Res Base-Address and is indexed
   sequentially from scanline 0-191 which avoids the
   ubiquituous venetian blind effect that we know and love */
extern unsigned HB[];

/*

The following is logically reordered to match the lores
color order...

                                                Repeated
                                                Binary
          Color         aux1  main1 aux2  main2 Pattern
          Black          00    00    00    00    0000
          Magenta        08    11    22    44    0001
		  Dark Blue      11    22    44    08    1000
          Violet         19    33    66    4C    1001
          Dark Green     22    44    08    11    0100
          Grey1          2A    55    2A    55    0101
          Medium Blue    33    66    4C    19    1100
          Light Blue     3B    77    6E    5D    1101
          Brown          44    08    11    22    0010
          Orange         4C    19    33    66    0011
          Grey2          55    2A    55    2A    1010
          Pink           5D    3B    77    6E    1011
          Green          66    4C    19    33    0110
          Yellow         6E    5D    3B    77    0111
          Aqua           77    6E    5D    3B    1110
          White          7F    7F    7F    7F    1111

*/

/*

#define LOBLACK   	0
#define LORED     	1
#define LODKBLUE 	2
#define LOPURPLE  	3
#define LODKGREEN	4
#define LOGRAY    	5
#define LOMEDBLUE	6
#define LOLTBLUE 	7
#define LOBROWN   	8
#define LOORANGE  	9
#define LOGREY    	10
#define LOPINK    	11
#define LOLTGREEN	12
#define LOYELLOW  	13
#define LOAQUA    	14
#define LOWHITE   	15

*/

/* the following array is based on the above */
extern unsigned char dhrbytes[16][4];


/* position of pixels in 4 byte pattern */
/* remember that byte 0 and byte 2 are auxmem
   and byte 1 and byte 3 are main mem
   and the 4 bit pattern of the 7 pixels straddle
   the two memory banks */

/* 7 pixels = 4 bytes */

/* left for reference...
unsigned char dhrpattern[7][4] = {
0,0,0,0,
0,0,0,1,
1,1,1,1,
1,1,2,2,
2,2,2,2,
2,3,3,3,
3,3,3,3};

*/

/* mask values to erase previous contents of pixels */
/* for reference

unsigned char dhrmsk[7][2] = {
0x70, 0,
0x0f, 0x7e,
0x61, 0,
0x1f, 0x7c,
0x43, 0,
0x3f, 0x78,
0x07, 0};

*/

/* getpixel mask values - what color to use */
/* for reference

unsigned char dhrgetmsk[7][2] = {
0x0f, 0,
0x70, 0x01,
0x1e, 0,
0x60, 0x03,
0x3c, 0,
0x40, 0x07,
0x78, 0};

*/


/* the following soft switches select between
   upper and lower banks of video memory */
extern char *dhrmain;
extern char *dhraux;


/* offset into memory frame for pixels */
/* double hi-res xbase */
/* for reference

char DHB[140] = {
0,0,0,0,0,0,0,
2,2,2,2,2,2,2,
4,4,4,4,4,4,4,
6,6,6,6,6,6,6,
8,8,8,8,8,8,8,
10,10,10,10,10,10,10,
12,12,12,12,12,12,12,
14,14,14,14,14,14,14,
16,16,16,16,16,16,16,
18,18,18,18,18,18,18,
20,20,20,20,20,20,20,
22,22,22,22,22,22,22,
24,24,24,24,24,24,24,
26,26,26,26,26,26,26,
28,28,28,28,28,28,28,
30,30,30,30,30,30,30,
32,32,32,32,32,32,32,
34,34,34,34,34,34,34,
36,36,36,36,36,36,36,
38,38,38,38,38,38,38};

*/


/* the crux of the filled-box-biscuit... */
int dhrflood(x1,y1,x2,y2,drawcolor)
int x1,y1,x2,y2,drawcolor;
{

    /* draws a filled box to the color specified */
    /* using double hi-res colors 0-16 */
    int packet = (x2-x1)+1, mainpack, auxpack;
    int temp,idx,xmain,xaux,xorg,bank;
    char *ptr;
    char membuf[40], auxbuf[40];

    y2++;

    xorg = x1%4; /* xorigin in 4 byte pattern */
    bank = x1%2; /* starting bank for first byte */
    xmain = (x1/2); /* the main offset... always */

    /* assign packet length */
    if (bank == 0) {
		xaux = xmain;
    	mainpack = packet / 2;
    	auxpack = packet - mainpack;
	}
	else {
		xaux = (xmain+1);
		auxpack = packet / 2;
		mainpack = packet - auxpack;
	}

    /* handle special cases first and */
    /* get the simple non-patterned algorithms out of the way */
    if (drawcolor < 1 || drawcolor > 16) drawcolor = 0;
    switch (drawcolor)
    {
		case 16:
		    /* pseudo-color 16 */
    		/* inverse video */
			while(y1<y2)
			{
				temp=HB[y1];
				if (auxpack > 0) {
					*dhraux = 0; /* select auxilliary memory */
					ptr = (char *)(temp+xaux);
                	idx = 0;
                	while(idx<auxpack)
                    {
                     *ptr^='\x7f';
                     *ptr++;
                      idx++;
                    }
					*dhrmain = 0; /* reset to main memory */
				}
				if (mainpack > 0)
					ptr = (char *)(temp+xmain);
                	idx = 0;
                	while(idx<mainpack)
                    {
                     *ptr^='\x7f';
                     *ptr++;
                      idx++;
                 }
				y1++;
			}
			return 0;	/* outa here */

		case 15: drawcolor = 127;
	    case 0:

	        /* white or black set the memory... */
			while(y1<y2)
			{
				temp=HB[y1];
				if (auxpack > 0) {
					*dhraux = 0;  /* select auxilliary memory */
					setmem((temp+xaux),auxpack,(char)drawcolor);
					*dhrmain = 0; /* reset to main memory */
				}
				if (mainpack > 0) setmem((temp+xmain),mainpack,(char)drawcolor);
				y1++;
			}
			return 0;	/* outa here */
	}

    /* now that we have adressed the simpler cases */
    /* we are left with repeating 4 byte patterns for the rest */
    /* set the color - colors 1-14 */
    /* assign byte pairs based on xorigin (seed the buffers) */
    switch(xorg)
    {
		/* make certain the 4 byte pattern starts correctly */
		/* these are kinda like ring buffers in a magically strange way
		   and speaking of magically strange ways... */

		/* The wikipedia article says this is complicated...
		   but doesn't go-on to say why and to explain further.
		   I say the whole double hi-res business is largely poorly documented
		   since often only part of the story is told by those who try to be
		   conscise but end-up not effectively communicating the necessary
		   information to make all this work. */

		case 0: auxbuf[0] = dhrbytes[drawcolor][0];
		        membuf[0] = dhrbytes[drawcolor][1];
		        auxbuf[1] = dhrbytes[drawcolor][2];
		        membuf[1] = dhrbytes[drawcolor][3];
		        break;

		case 1: membuf[0] = dhrbytes[drawcolor][1];
		        auxbuf[0] = dhrbytes[drawcolor][2];
		        membuf[1] = dhrbytes[drawcolor][3];
		        auxbuf[1] = dhrbytes[drawcolor][0];
		        break;

		case 2: auxbuf[0] = dhrbytes[drawcolor][2];
		        membuf[0] = dhrbytes[drawcolor][3];
		        auxbuf[1] = dhrbytes[drawcolor][0];
		        membuf[1] = dhrbytes[drawcolor][1];
		        break;

		case 3: membuf[0] = dhrbytes[drawcolor][3];
		        auxbuf[0] = dhrbytes[drawcolor][0];
		        membuf[1] = dhrbytes[drawcolor][1];
		        auxbuf[1] = dhrbytes[drawcolor][2];
		        break;
	}

    /* expand byte pairs to build scanline buffers */
    for (idx = 2; idx < auxpack; idx++) {
		auxbuf[idx] = auxbuf[0];
		idx++;
		auxbuf[idx] = auxbuf[1];
	}
    for (idx = 2; idx < mainpack; idx++) {
		membuf[idx] = membuf[0];
		idx++;
		membuf[idx] = membuf[1];
	}

   /* now write the pixels */
   while(y1<y2)
   {
	temp=HB[y1];
	if (auxpack > 0) {
		*dhraux = 0;  /* select auxilliary memory */
		movmem(auxbuf,(temp+xaux),auxpack);
		*dhrmain = 0; /* reset to main memory */
	}
	if (mainpack > 0) movmem(membuf,(temp+xmain),mainpack);
    y1++;
   }

return 0;

}

